package com.example.myapplication.customizeView.slide;

import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;
import android.widget.TextView;

import com.example.myapplication.R;

public class SlideMenuView extends ViewGroup implements View.OnClickListener {

    private static final String TAG = "SlideMenuView";
    private int mFunction;
    private View mContentView;
    private View editView;
    private View mEditView;
    private TextView mReadTv;
    private TextView mTopTv;
    private TextView mDeleteTv;
    private OnEditClickListener mEditClickListener = null;
    private float mDownX;
    private float mDownY;
    private Scroller mScroller;
    //是否已经打开
    private boolean isOpen = false;
    private Direction mCurrentDirection = Direction.NONE;
    private float mInterceptDownX;
    private float mInterceptDownY;

    public boolean isOpen() {
        return isOpen;
    }

    enum Direction{
        LEFT,RIGHT,NONE
    }
    //动画时间 mDuration,mEditView走完4/5所花费的时间
    private int mMaxDuration = 800;
    private int mMinDuration = 300;

    public SlideMenuView(Context context) {
        this(context,null);
    }

    public SlideMenuView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public SlideMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideMenuView);
        mFunction = a.getInt(R.styleable.SlideMenuView_function, 0x30);
        a.recycle();
        mScroller = new Scroller(context);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        int childCount = getChildCount();
        Log.d(TAG,"childCount--==>"+childCount);
        //添加判断：只能有一个子View
        if (childCount>1) {
            throw new IllegalArgumentException("子View大于1");
        }
        mContentView = getChildAt(0);
        //根据属性，继续添加子View
        mEditView = LayoutInflater.from(getContext()).inflate(R.layout.item_slide_action, this, false);
        inEditView();
        this.addView(mEditView);
        int afterCount = getChildCount();
        Log.d(TAG,"afterCount--==>"+afterCount);
    }

    private void inEditView() {
        mReadTv = mEditView.findViewById(R.id.read_tv);
        mTopTv = mEditView.findViewById(R.id.top_tv);
        mDeleteTv = mEditView.findViewById(R.id.delete_tv);
        mReadTv.setOnClickListener(this);
        mTopTv.setOnClickListener(this);
        mDeleteTv.setOnClickListener(this);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        //测量第一个子View,就是内容部分
        //宽度和父容器一样，高度有三种
        //高度：wrap_content,match_parent,自定义高度
        LayoutParams contentLayoutParams = mContentView.getLayoutParams();
        int contentHeight = contentLayoutParams.height;
        int contentHeightMeasureSpec;

        //高度的三种状态
        if (contentHeight==LayoutParams.MATCH_PARENT){
             contentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);

        }else if(contentHeight==LayoutParams.WRAP_CONTENT){
            contentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);

        }else{
            //自定义大小的
            contentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(contentHeight, MeasureSpec.EXACTLY);

        }
        mContentView.measure(widthMeasureSpec,contentHeightMeasureSpec);

        //拿到内容部分测量以后高度
        int contentMeasureHeight = mContentView.getMeasuredHeight();
        //测量编辑部分,宽度 3/4，高度和内容一样

        int editWidthSize = widthSize *  3/4;
        mEditView.measure(MeasureSpec.makeMeasureSpec(editWidthSize,MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(contentMeasureHeight,MeasureSpec.EXACTLY));
        //测量自己
        //宽度是前面两个子View的宽度总和，高度和内容一致

        setMeasuredDimension(widthSize+editWidthSize,contentMeasureHeight);

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        //摆放内容
        int contentLeft = 0;
        int contentTop = 0;
        int contentRight = contentLeft+mContentView.getMeasuredWidth();
        int contentBottom = contentTop + mContentView.getMeasuredHeight();

        mContentView.layout(contentLeft,contentTop,contentRight,contentBottom);
        //摆放编辑部分
        int editViewLeft = contentRight;
        int editViewTop = contentTop;
        int editViewRight = editViewLeft + mEditView.getMeasuredWidth();
        int editViewBottom = editViewTop +mEditView.getMeasuredHeight();
        mEditView.layout(editViewLeft,editViewTop,editViewRight,editViewBottom);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action){
            case ACTION_DOWN:
                mDownX = event.getX();
                mDownY = event.getY();
                Log.d(TAG, "downX---> "+ mDownX);
                Log.d(TAG, "downY---> "+ mDownY);
                Log.d(TAG,"ACTION_DOWN");
                break;
            case ACTION_MOVE:
                int scrollX = getScrollX();
                float moveX = event.getX();
                float moveY = event.getY();
                //移动的差值
                int dx = (int) (moveX - mDownX);
               // Log.d(TAG,"dx==>"+dx);用于测试dx值正数右移，dx值负数左移
                if (dx>0){
                    mCurrentDirection=Direction.RIGHT;
                }else{
                    mCurrentDirection=Direction.LEFT;
                }
                //判断边界
                int resultScrollX = -dx + scrollX;
                if (resultScrollX <= 0){
                    scrollTo(0,0);
                }else if(resultScrollX > mEditView.getMeasuredWidth()) {
                    scrollTo(mEditView.getMeasuredWidth(),0);

                }else{
                    scrollBy(-dx,0);
                    }

                mDownX = moveX;
                mDownY = moveY;
                Log.d(TAG, "moveX---> "+moveX);
                Log.d(TAG, "moveY---> "+moveY);
                Log.d(TAG,"ACTION_MOVE");
                break;
            case ACTION_UP:
                float upX = event.getX();
                float upY = event.getY();
                int hasBeScrollX = getScrollX();
                int mEditViewWidth = mEditView.getMeasuredWidth();
                //处理释放后是显示还是收缩回去
                //两个关注点：是否已经打开isOpen，方向
                if (isOpen){
                    //当前状态打开
                    if (mCurrentDirection==Direction.RIGHT){
                        //如果小于4/5就关闭，大于就打开
                        if (hasBeScrollX<=mEditViewWidth*4/5){
                            close();
                        }else{
                            open();
                        }

                    }else if (mCurrentDirection==Direction.LEFT){
                        open();

                    }
                }else{
                    //当前状态关闭
                    if (mCurrentDirection==Direction.LEFT){
                        //左滑
                        if (hasBeScrollX>mEditViewWidth/5){
                            open();
                        }else{
                            close();
                        }

                    }else if(mCurrentDirection==Direction.RIGHT){
                        //右滑
                        close();
                    }

                }
                Log.d(TAG, "upX---> "+upX);
                Log.d(TAG, "upY---> "+upY);
                Log.d(TAG,"ACTION_UP");
                break;

        }
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //选择拦截
        switch (ev.getAction()) {
            case ACTION_DOWN:
                mInterceptDownX = ev.getX();
                mInterceptDownY = ev.getY();
                break;
            case ACTION_MOVE:
                float x = ev.getX();
                float y = ev.getY();
                if (Math.abs(x-mInterceptDownX)>0){
                    return true;
                }
                break;
            case ACTION_UP:
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    public void open(){
        //滑动值大于编辑部分的一半，显示
        //scrollTo(mEditView.getMeasuredWidth(),0);
        int dx = mEditView.getMeasuredWidth() - getScrollX();
        int duration = (int) (dx/(mEditView.getMeasuredWidth()*4/5f)* mMaxDuration);
        int absDuration=Math.abs(duration);
        if (absDuration<mMinDuration){
            absDuration=mMinDuration;
        }


        mScroller.startScroll(getScrollX(),0,dx,0,absDuration);
        invalidate();
        isOpen = true;


    }

    public void close(){
        //滑动值小于编辑部分的一半，隐藏
        //scrollTo(0,0);
        //添加一个滑动的延时效果
        int dx = -getScrollX();
        int duration = (int) (dx/(mEditView.getMeasuredWidth()*4/5f)* mMaxDuration);
        int absDuration=Math.abs(duration);
        if (absDuration<mMinDuration){
            absDuration=mMinDuration;
        }
        mScroller.startScroll(getScrollX(),0,dx,0,absDuration);
        invalidate();
        isOpen = false;

    }

    @Override
    public void computeScroll() {
       if (mScroller.computeScrollOffset()){
           int currX = mScroller.getCurrX();
           //滑动到指定位置
           scrollTo(currX,0);
           invalidate();
       }
    }

    /**
     * 动作的监听
     */

    public void setOnEditClickListener(OnEditClickListener listener){
        this.mEditClickListener = listener;

    }

    @Override
    public void onClick(View v) {
        close();
        if (mEditClickListener == null) {
            return;
        }
        if (v==mReadTv){
            mEditClickListener.onReadClick();

        }else if (v==mTopTv){
            mEditClickListener.onTopClick();

        }else if(v==mDeleteTv){
            mEditClickListener.onDeleteClick();

        }


    }

    public interface OnEditClickListener{
        void onReadClick();
        void onTopClick();
        void onDeleteClick();
    }

}
